import random
import re

from django.contrib.auth.hashers import make_password
from django.http import HttpResponse
from rest_framework.response import Response
from rest_framework.views import APIView

from users.ser import *
from utils.comm import send_message, get_redis
from users.models import *


# 测试
class Text(APIView):
    def get(self, request):
        conn = get_redis()
        conn.setex('username', 10, 'xiaoming236')
        name = conn.get('username')
        return Response(name)


# 注册
class Register(APIView):
    def post(self, request):

        # 用户名
        username = request.data.get('username')
        if not username:
            return Response({'code': 10010})
        # 格式是否正确
        name = re.match('\w{5,10}$', username)
        if not name:
            return Response({'code': 10011})
        # 是否唯一
        user = User.objects.filter(username=username).first()
        if user:
            return Response({'code': 10012})

        # 密码
        password = request.data.get('password')
        if not password:
            return Response({'code': 10013})
        # 格式是否正确
        pwd = re.match('\w{3,6}$', password)
        if not pwd:
            return Response({'code': 10014})

        # 手机号
        mobile = request.data.get('mobile')
        if not mobile:
            return Response({'code': 10016})
        phone = re.match('^1[3-9]\d{9}$', mobile)
        if not phone:
            return Response({'code': 10017})
        # 是否唯一
        sloe = User.objects.filter(mobile=mobile).first()
        if sloe:
            return Response({'code': 10018})

        # 验证码验证
        smscode = request.data.get('smscode')
        conn = get_redis()
        code = conn.get(mobile)
        if code:
            code = str(code, encoding='utf8')
        if smscode != code:
            return Response({'code': 10019})

        return Response({'code': 200, 'meg': '注册成功'})


# 验证码
class SendSms(APIView):
    def post(self, request):
        mobile = request.data.get('mobile')
        # 验证图片验证码,通过后发短信
        uid = request.data.get('uid')
        imagecode = request.data.get('imagecode')
        conn = get_redis()
        imgcode = conn.get(uid)
        if imgcode:
            imgcode = str(imgcode, encoding='utf8')
            if imagecode.lower() == imgcode.lower():
                codesms = random.randint(1000, 9999)
                res = send_message(mobile, str(codesms), 1)
                if res:
                    # 发生成功后存入redis
                    conn = get_redis()
                    conn.setex(mobile, 60, codesms)
                    # 判断是否同意协议
                    agree = request.data.get('agree')
                    if not agree:
                        return Response({'code': 10020})
                    # 注册功能
                    request.data['password'] = make_password(request.data.get('password'))
                    ser = UserModel(data=request.data)
                    if ser.is_valid():
                        ser.save()
                        return Response({'code': 200})
                    return Response({'code': 10021})


# 生成图片验证码
from utils.captcha.captcha import captcha


class CreateCaptcha(APIView):
    def get(self, request):
        uuid = request.GET.get('uuid')
        name, text, img = captcha.generate_captcha()
        # redis存储
        conn = get_redis()
        conn.set(uuid, text)
        return HttpResponse(img, content_type='image/jpg')


# 添加地址
class AddressM(APIView):
    def post(self, request):
        ser = AddressModel(data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({'code': 200})

    def get(self, request):
        userid = request.GET.get('userid')
        address = Address.objects.filter(user_id=userid).all()
        ser = AddressModel(address, many=True)
        return Response({'code': 200, 'list': ser.data})

    def put(self, request):
        # 获取id
        id = request.GET.get('id')
        # 通过id查询
        address = Address.objects.filter(id=id).first()
        # 根据userid和is_default=1更新is_default=0
        Address.objects.filter(user_id=address.user_id, is_default=1).update(is_default=0)
        # 把当前id设置成默认5
        address.is_default = 1
        address.save()
        return Response({"code": 200})


# 首页展示
def xTree(datas):
    list = []
    tree = {}
    for i in datas:
        tree[i['id']] = i

    for i in datas:
        parent = i['parent']
        if not parent:
            list.append(i)
        else:
            if 'son' not in tree[parent]:
                tree[parent]['son'] = []
            tree[parent]['son'].append(i)
    return list


# 读取首页三级分类
class Home(APIView):
    def get(self, request):
        # 读取一级
        cates = Category.objects.filter(parent_id__isnull=True).all()
        list = []
        for i in cates:
            dict = {}
            dict['id'] = i.id
            dict['name'] = i.name
            # 读取二级
            two = i.subs.all()
            twolist = []
            # 遍历二级获取三级
            for j in two:
                twodict = {}
                twodict['id'] = j.id
                twodict['name'] = j.name
                three = j.subs.all()
                ser = CateSer(three, many=True)
                twodict['subs'] = ser.data
                twolist.append(twodict)

                dict['subs'] = twolist
                list.append(dict)
                categoods = []
                for j in cates:
                    dict = {}
                    dict['id'] = j.id
                    dict['name'] = j.name
                    dict['pic'] = str(j.pic)
                    two = j.subs.all()
                    twoser = CateSer(two, many=True)
                    dict['two'] = twoser.data
                    # 获取三级
                    three = Category.objects.filter(top_parent=j.id, level=3).all()
                    threeser = CateSer(three, many=True)
                    dict['three'] = threeser.data
                    # 获取商品,排序，新品按时间倒序排，价格，销量
                    sorted = request.GET.get('sorted')
                    topid = request.GET.get('topid')

                    goods = Goods.objects.filter(category1_id=j.id, home_show=1).all()
                    if sorted:
                        if int(topid) == int(j.id):
                            goods = Goods.objects.filter(category1_id=j.id, home_show=1).order_by('-' + sorted).all()

                    gser = GoodsSer(goods, many=True)
                    dict['goods'] = gser.data
                    categoods.append(dict)
                return Response({"code": 200, 'catelist': list, 'categoods': categoods})


#  商品详情页
class GoodsM(APIView):
    def get(self, request):
        id = request.GET.get('id')
        good = Goods.objects.filter(id=id).first()
        ser = GoodsSer(good)
        return Response({"code": 200, 'good': ser.data})


# 购物车页面
class CartM(APIView):
    def post(self, request):
        # 判断此用户是否购买过此商品
        userid = request.data.get('user')
        goodsid = request.data.get('goods')
        number = int(request.data.get('number'))
        cart = Cart.objects.filter(user_id=userid, goods_id=goodsid).first()
        if cart:
            # 如果买过数量+
            cart.number += number
            cart.save()
            return Response({"code": 200})
        else:
            # 没买过购物车新增一条记录
            ser = CartModel(data=request.data)
            if ser.is_valid():
                ser.save()
                return Response({"code": 200})
            else:
                print(ser.errors)
                return Response({"code": 10010})

    def get(self, request):
        userid = request.GET.get('userid')
        cart = Cart.objects.filter(user_id=userid).all()
        ser = CartModel(cart, many=True)
        # 全选
        selected_all = True
        total = 0
        select_total = 0
        select_money = 0
        for i in cart:
            total += i.number
            if i.is_checked == False:
                selected_all = False
            else:
                select_total += i.number
                goods = Goods.objects.filter(id=i.goods_id).first()
                select_money += i.number * float(goods.price)

        return Response(
            {"code": 200, 'list': ser.data, 'selected_all': selected_all, 'total': total, 'select_total': select_total,
             'select_money': select_money})

    def put(self, request):
        id = request.GET.get('id')
        cart = Cart.objects.filter(id=id).first()
        if cart.is_checked == True:
            cart.is_checked = False
        else:
            cart.is_checked = True
        cart.save()
        return Response({"code": 200})


# 全选
class SelectAll(APIView):
    def put(self, request):
        userid = request.GET.get('userid')
        selected_all = request.GET.get('selected_all')
        if selected_all == 'true':
            Cart.objects.filter(user_id=userid).update(is_checked=True)
        else:
            Cart.objects.filter(user_id=userid).update(is_checked=False)
        return Response({'code': 200})

    def post(self, request):
        id = request.data.get('id')
        type = request.data.get('type')
        count = request.data.get('count')
        cart = Cart.objects.filter(id=id).first()
        if type == 1:
            # 加
            cart.number += 1
        elif type == 2:
            # 减
            # 判断是否>1
            if cart.number > 1:
                cart.number -= 1
        else:
            # 数量更新
            cart.number = int(count)
        cart.save()
        return Response({"code": 200})


# 确认订单
class GetCheckCart(APIView):
    def get(self, request):
        # 获取userid
        userid = request.GET.get('userid')
        # 通过userid,is_checked=true查询
        cart = Cart.objects.filter(user_id=userid, is_checked=True).all()
        ser = CartModel(cart, many=True)
        total = 0
        tmoney = 0
        for i in ser.data:
            # 查询总数量
            total += i['number']
            # 查询总金额
            tmoney += i['number'] * float(i['goods']['price'])
        # 返回结果
        return Response({"code": 200, 'list': ser.data, 'total': total, 'tmoney': tmoney})


import datetime
import random
from django.db import transaction


# 生成订单
class CreateOrders(APIView):
    @transaction.atomic
    def post(self, request):
        # 获取userid
        userid = request.data.get('userid')
        address_id = request.data.get('address_id')
        pay_method = request.data.get('pay_method')
        # 根据userid查询购物车中已经选中的记录
        cart = Cart.objects.filter(user_id=userid, is_checked=True).all()
        cartser = CartModel(cart, many=True)
        # 遍历购物车
        total_amount = 0
        for i in cartser.data:
            total_amount += i['number'] * float(i['goods']['price'])
        # 生成订单号
        order_no = datetime.datetime.strftime(datetime.datetime.now(), '%Y%m%d%H%m%s') + str(userid) + str(
            random.randint(1000, 9999))
        # 查找地址构造地址信息
        add = Address.objects.filter(id=address_id).first()
        addressSer = AddressModel(add)
        address = addressSer.data
        addressStr = address['province'] + ' ' + address['city'] + ' ' + address['area'] + ' ' + address[
            'address'] + ' ' + address['receive'] + ' ' + address['mobile']

        datam = {'order_no': order_no, 'user': userid, 'address': addressStr, 'total_amount': total_amount,
                 'pay_method': pay_method}
        # 创建事务结点
        sid = transaction.savepoint()
        try:
            # 调用序列化器添加订单
            ser = OrderInfoSer(data=datam)
            if ser.is_valid():
                ser.save()
                # 生成订单详情
                for i in cartser.data:
                    detaildata = {'order': order_no, 'goods': i['goods']['id'], 'goodsname': i['goods']['name'],
                                  'images': i['goods']['pic'], 'count': i['number'],
                                  'price': float(i['goods']['price']), 'user': userid}
                    # 调用序列化器添加订单详情
                    dser = OrderDetailSer(data=detaildata)
                    if dser.is_valid():
                        dser.save()
            # 购物车删除已经生成订单的记录
            Cart.objects.filter(user_id=userid, is_checked=True).delete()
            # 提交事务
            transaction.savepoint_commit(sid)
            # 返回结果
            return Response({'code': 200, 'order_no': order_no, 'tmoney': total_amount})
        except:
            # 事务回滚
            transaction.savepoint_rollback(sid)
            return Response({'code': 20010})